package com.hebeu.xwl.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hebeu.xwl.config.DynamicTableTreadLocal;
import com.hebeu.xwl.dao.BatchDao;
import com.hebeu.xwl.dao.DataDao;
import com.hebeu.xwl.dao.hivedao.ArticleDao;
import com.hebeu.xwl.dao.LogDao;
import com.hebeu.xwl.dao.UserDao;
import com.hebeu.xwl.pojo.Article;
import com.hebeu.xwl.pojo.Batch;
import com.hebeu.xwl.pojo.Data;
import com.hebeu.xwl.pojo.Log;
import com.hebeu.xwl.service.ArticleService;
import com.hebeu.xwl.vo.PageVo;
import com.hebeu.xwl.vo.SearchVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.security.SecureRandom;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleDao,Article> implements ArticleService {

    @Autowired
    private ArticleDao articleDao;

    @Autowired
    private UserDao userDao;

    @Autowired
    private BatchDao batchDao;

    @Autowired
    private LogDao logDao;

    @Autowired
    private DataDao dataDao;
    @Override
    public void createTable(String index){
        articleDao.hiveCreatTable(index);
    }
    @Override
    public void addArticle(Article article, String index){
        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        articleDao.insert(article);
    }


    @Override
    public List<Article> findAll(String index, int userId){

        LambdaQueryWrapper<Batch> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Batch::getIndex,index);
        int batchId = batchDao.selectOne(wrapper1).getBatchId();

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index+"中的所有数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        //插入日志
        logDao.insert(log);


        //设置表名
        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByAsc(Article::getArticleId);
        return articleDao.selectList(wrapper);
    }

    /**
     *
     * @param index     表名
     * @param userId    用户id
     * @param page      页码
     * @return
     */
    @Override
    public PageVo<Article> pageFind(String index, int userId, int page) {

        LambdaQueryWrapper<Batch> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Batch::getIndex,index);
        int batchId = batchDao.selectOne(wrapper1).getBatchId();

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index+"中的第"+page+"页数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        //插入日志
        logDao.insert(log);


        //设置表名
        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        PageVo<Article> pageVo = new PageVo<>();
        int recordOfPage = 10;//每页显示的数据
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.between(Article::getArticleId,(page-1)*recordOfPage+1,page*recordOfPage);
        wrapper.orderByAsc(Article::getArticleId);
        List<Article> articleList = articleDao.selectList(wrapper);

        int recordCount = Math.toIntExact(articleDao.selectCount(null));//数据总数
        int pageCount = ((recordCount-1)/recordOfPage)+1;//总页数

        pageVo.setPage(page);
        pageVo.setRecordOfPage(recordOfPage);
        pageVo.setPageCount(pageCount);
        pageVo.setRecordCount(recordCount);
        pageVo.setList(articleList);

        return pageVo;
    }

    public static String filter(String content){
        if (content != null && content.length() > 0) {
            char[] contentCharArr = content.toCharArray();
            for (int i = 0; i < contentCharArr.length; i++) {
                if (contentCharArr[i] < 0x20 || contentCharArr[i] == 0x7F) {
                    System.out.println("已经被替换为空格！");
                    contentCharArr[i] = 0x20;
                }
            }

            return new String(contentCharArr);
        }
        return "";
    }


    @Override
    @DS("hive")
    public void addArticleList(List<Article> articleList, String index, int userId) {
        //设置表名
        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        //获取文章表中id的最大值
        QueryWrapper<Article> wrapper = new QueryWrapper<>();
        wrapper.select("max(articleId) as maxId");
        List<Map<String,Object>> mapList = articleDao.selectMaps(wrapper);
        int maxArticleId = 0;
        if(mapList.get(0) != null){
            Integer maxId = (Integer)mapList.get(0).get("maxId");
            maxArticleId = maxId;
        }
        //获取要添加的数据量
        int batchcount = articleList.size();
        //保存到表内
        for(Article article:articleList)
        {
            article.setArticleId(maxArticleId+1);
            articleDao.insert(article);
            maxArticleId = maxArticleId +1;
        }
        LambdaQueryWrapper<Batch> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Batch::getIndex,index);
        Batch batch = batchDao.selectOne(wrapper1);
        int batchId = batch.getBatchId();
        batch.setArticlenum(batch.getArticlenum() + batchcount);
        batchDao.updateById(batch);
        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("向id为"+batchId+"数据集："+index+"中增加"+articleList.size()+"条数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);
    }

    @Override
    public void overwrite(List<Article> articleList, String index, int userId){
        DynamicTableTreadLocal.INSTANCE.setTableName(index);

        Article article = articleList.get(0);
        articleDao.overwrite(index,1,article.getAuthor(),article.getPubdate()
        ,article.getPubtime(),article.getTitle(),article.getKeywords(),article.getHref(),
                article.getLikes(),article.getCommentary(),article.getViews());
        int batchcount = articleList.size();
        int maxArticleId = 1;
        for(int i= 1;i <articleList.size();i++){
            Article article1 = articleList.get(i);
            article1.setArticleId(maxArticleId+1);
            articleDao.insert(article1);
            maxArticleId = maxArticleId +1;
        }

        LambdaQueryWrapper<Batch> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Batch::getIndex,index);
        //修改表内总数
        Batch batch = batchDao.selectOne(wrapper1);
        int batchId = batch.getBatchId();
        batch.setArticlenum(batchcount);
        batchDao.updateById(batch);

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("覆盖id为"+batchId+"数据集："+index+"中的数据，新增"+articleList.size()+"条数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

    }

    /**
     * 用来查找指定文章表中的数据量，用来判断是否超过上限
     * @param index
     * @return int 文章数量
     */
    @Override
    public int findArticleNum(String index){
        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        return Math.toIntExact(articleDao.selectCount(null));
    }


    /**
     * 根据日期查文章发布量
     * @param userId
     * @param batchId
     * @return
     */
    @Override
    public String countByPubdate(int userId,int batchId){

        String strdata ;

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"1").
                eq(Data::getFactors,"无");
        Data data  = dataDao.selectOne(wrapper);

        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.countByPubdate(index);
            String str = JSONObject.toJSONString(mapdata);


            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("1");
            data01.setFactors("无");
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index+"中，各个日期的文章发布量");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }


    /**
     * 查看单一作者每个日期的文章发布量
     * @param userId
     * @param batchId
     * @param author
     * @return
     */
    @Override
    public String countByPubdateAndAuthor(int userId,int batchId,String author){

        String strdata ;

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"1").
                eq(Data::getFactors,author);
        Data data  = dataDao.selectOne(wrapper);

        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.countByPubdateAndAuthor(index,author);
            String str = JSONObject.toJSONString(mapdata);

            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("1");
            data01.setFactors(author);
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index+"中，作者："+author+"各个日期的文章发布量");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }

    @Override
    public String keywordsCount(int userId,int batchId){
        String strdata ;
        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();
        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"2").
                eq(Data::getFactors,"无");
        Data data  = dataDao.selectOne(wrapper);
        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.keywordsCount(index);
            String str = JSONObject.toJSONString(mapdata);

            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("2");
            data01.setFactors("无");
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index+"中各个关键字出现的次数");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }

    @Override
    public String keywordsCountByAuthor(int userId,int batchId,String author){
        String strdata ;
        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();
        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"2").
                eq(Data::getFactors,author);
        Data data  = dataDao.selectOne(wrapper);
        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.keywordsCountByAuthor(index,author);
            String str = JSONObject.toJSONString(mapdata);

            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("2");
            data01.setFactors(author);
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index
                +"中作者："+author+"发布的文章中的各个关键字出现的次数");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }

    @Override
    public String sumLikesByAuthor(int userId,int batchId){
        String strdata ;
        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();
        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"3").
                eq(Data::getFactors,"likes");
        Data data  = dataDao.selectOne(wrapper);
        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.sumLikesByAuthor(index);
            String str = JSONObject.toJSONString(mapdata);

            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("3");
            data01.setFactors("likes");
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index
                +"中各个作者发布的文章的总喜欢次数");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }

    @Override
    public String sumViewsByAuthor(int userId,int batchId){
        String strdata ;
        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();
        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"3").
                eq(Data::getFactors,"views");
        Data data  = dataDao.selectOne(wrapper);
        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.sumViewsByAuthor(index);
            String str = JSONObject.toJSONString(mapdata);

            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("3");
            data01.setFactors("views");
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index
                +"中各个作者发布的文章的总浏览量");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }

    @Override
    public String sumCommentaryByAuthor(int userId,int batchId){
        String strdata ;
        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();
        LambdaQueryWrapper<Data> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Data::getBatchId,batchId).
                eq(Data::getChartType,"3").
                eq(Data::getFactors,"commentary");
        Data data  = dataDao.selectOne(wrapper);
        if(data == null){
            DynamicTableTreadLocal.INSTANCE.setTableName(index);
            List<Map<String,Object>> mapdata = articleDao.sumCommentaryByAuthor(index);
            String str = JSONObject.toJSONString(mapdata);

            Data data01 = new Data();
            data01.setBatchId(batchId);
            data01.setChartType("3");
            data01.setFactors("commentary");
            data01.setData(str);
            dataDao.insert(data01);

            strdata = str;
        }else {
            String strdata01 = data.getData();
            strdata = strdata01;
        }

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为"+batchId+"的数据集："+index
                +"中各个作者发布的文章的总评论量");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return strdata;
    }

    @Override
    public List<Article> findArticleByPubdate(int userId,int batchId,String pubdate){

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getPubdate,pubdate);
        List<Article> articleList = articleDao.selectList(wrapper);

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为："+batchId+"的数据集："+index
                +"中在日期："+pubdate+"发布的文章数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return articleList;

    }
    @Override
    public List<Article> findArticleByPubdateAndAuthor(
            int userId,int batchId,String pubdate,String author){

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getPubdate,pubdate);
        wrapper.eq(Article::getAuthor,author);
        List<Article> articleList = articleDao.selectList(wrapper);

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为："+batchId+"的数据集："+index
                +"中作者："+author+"在日期："+pubdate+"发布的文章数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return articleList;

    }

    @Override
    public List<Article> findArticleByAuthor(int userId,int batchId,String author){

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Article::getAuthor,author);
        List<Article> articleList = articleDao.selectList(wrapper);

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为："+batchId+"的数据集："+index
                +"中作者："+author+"发布的文章数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return articleList;
    }

    @Override
    public List<Article> findArticleByKeywords(int userId,int batchId,String keywords){

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Article::getKeywords,keywords);
        List<Article> articleList = articleDao.selectList(wrapper);

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为："+batchId+"的数据集："+index
                +"中有关："+keywords+"的文章数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return articleList;

    }

    @Override
    public List<Article> findArticleByKeywordsAndAuthor(
            int userId,int batchId,String keywords,String author){

        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Article::getKeywords,keywords);
        wrapper.eq(Article::getAuthor,author);
        List<Article> articleList = articleDao.selectList(wrapper);

        Log log = new Log();
        log.setUserId(userId);
        log.setRecord("查看id为："+batchId+"的数据集："+index
                +"中作者："+author+"发布的有关"+keywords+"的文章数据");
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return articleList;

    }

    @Override
    public List<Article> findArticleBySearchVo(int userId, int batchId, SearchVo searchVo){
        Batch batch = batchDao.selectById(batchId);
        String index = batch.getIndex();

        Log log = new Log();
        StringBuilder record = new StringBuilder("查看id为：" + batchId + "的数据集：" + index + "中");

        DynamicTableTreadLocal.INSTANCE.setTableName(index);
        LambdaQueryWrapper<Article> wrapper = new LambdaQueryWrapper<>();
        if(searchVo.getAuthor() != null && !"".equals(searchVo.getAuthor())){
            wrapper.eq(Article::getAuthor,searchVo.getAuthor());
            record.append("作者:"+searchVo.getAuthor());
        }
        if(searchVo.getPubdate() != null && !"".equals(searchVo.getPubdate())){
            wrapper.eq(Article::getPubdate,searchVo.getPubdate());
            record.append("在日期："+searchVo.getPubdate()+"发布的");
        }
        if(searchVo.getKeywords() != null && !"".equals(searchVo.getKeywords())){
            wrapper.like(Article::getKeywords,searchVo.getKeywords());
            record.append("有关："+ searchVo.getKeywords()+"的");
        }
        List<Article> articleList = articleDao.selectList(wrapper);

        record.append("文章的数据");
        log.setUserId(userId);
        log.setRecord(record.toString());
        Date date = new Date();
        long time = (date.getTime()/1000);
        log.setTime(time);
        logDao.insert(log);

        return articleList;
    }



}
